using System;
using GameFrameworkLibraly.BaseObjects;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GameFrameworkLibraly.Controls
{
    public abstract class CheckableControl:Control
    {
        protected bool CheckedField;
        private Rectangle _textureRectangle;
        private Vector2 _textPosition;

        /// <summary>
        /// Creates a new instance of check box
        /// </summary>
        /// <param name="game">Current game</param>
        /// <param name="destinationRectangle">Defines rectangle where the control must be drawn</param>
        /// <param name="checkedTexture">Texture that will be drawn when checkbox is checked</param>
        /// <param name="uncheckedTexture">Texture that will be drawn when checkbox isn't checked</param>
        protected CheckableControl(MyGame game, Rectangle destinationRectangle, Texture2D checkedTexture, Texture2D uncheckedTexture):base(game)
        {
            DestinationRectangle = destinationRectangle;
            CheckedTexture = checkedTexture;
            UncheckedTexture = uncheckedTexture;

            DestinationRectangleChanged += CheckBoxControlDestinationRectangleChanged;
            RecalculateTextureRectangle();
        }

        /// <summary>
        /// Creates a new instance of check box
        /// </summary>
        /// <param name="game">Current game</param>
        /// <param name="destinationRectangle">Defines rectangle where the control must be drawn</param>
        /// <param name="checkedTexture">Texture that will be drawn when checkbox is checked</param>
        /// <param name="uncheckedTexture">Texture that will be drawn when checkbox isn't checked</param>
        /// <param name="text">Text that will be printed near checkbox</param>
        /// <param name="spriteFont">SpriteFont that will be used to print text</param>
        protected CheckableControl(MyGame game, Rectangle destinationRectangle, Texture2D checkedTexture, Texture2D uncheckedTexture, string text, SpriteFont spriteFont)
            : this(game,destinationRectangle, checkedTexture, uncheckedTexture)
        {
            Text = text;
            SpriteFont = spriteFont;
        }

        void CheckBoxControlDestinationRectangleChanged(object sender, EventArgs e)
        {
            RecalculateTextureRectangle();
        }

        /// <summary>
        /// Text that will be printed near checkbox
        /// </summary>
        public virtual string Text { get; set; }
        
        /// <summary>
        /// SpriteFont that will be used to print text
        /// </summary>
        public SpriteFont SpriteFont { get; set; }

        /// <summary>
        /// Texture that will be drawn when checkbox is checked
        /// </summary>
        public Texture2D CheckedTexture { get; set; }

        /// <summary>
        /// Texture that will be drawn when checkbox isn't checked
        /// </summary>
        public Texture2D UncheckedTexture { get; set; }


        /// <summary>
        /// Indicates if the checkbox is checked
        /// </summary>
        public bool Checked
        {
            get { return CheckedField; }
            set
            {
                CheckedField = value;
                InvokeCheckedChanged(EventArgs.Empty);
                if(CheckedField)
                    InvokeItemSelected(EventArgs.Empty);
            }
        }

        /// <summary>
        /// Occures when checked property was changed
        /// </summary>
        public event EventHandler CheckedChanged;

        /// <summary>
        /// Occures when item was selected
        /// </summary>
        public event EventHandler ItemSelected;
        
        #region Control

        /// <summary>
        /// Draws the control
        /// </summary>
        /// <param name="spriteBatch"></param>
        public override void Draw(SpriteBatch spriteBatch)
        {
            if(!Visible)
                return;
            if(BackgroundTexture!=null)
                spriteBatch.Draw(BackgroundTexture,DestinationRectangle,BackColorFilter);
            spriteBatch.Draw(Checked ? CheckedTexture : UncheckedTexture, _textureRectangle, ForeColor);
            if (SpriteFont != null && !string.IsNullOrEmpty(Text))
            {
                spriteBatch.DrawString(SpriteFont,Text,_textPosition,ForeColor);
            }
        }

        /// <summary>
        /// Updates state of the control
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            if (!Enabled)
                return;
            if (SpriteFont != null && !string.IsNullOrEmpty(Text))
            {
                Vector2 textSize = SpriteFont.MeasureString(Text);
                _textPosition = new Vector2(_textureRectangle.Right+5,
                                            (int)(DestinationRectangle.Top + (DestinationRectangle.Height - textSize.Y) / 2));
            }
        }

        #endregion

        protected void InvokeCheckedChanged(EventArgs e)
        {
            EventHandler handler = CheckedChanged;
            if (handler != null) handler(this, e);
        }

        public void InvokeItemSelected(EventArgs e)
        {
            EventHandler handler = ItemSelected;
            if (handler != null) handler(this, e);
        }

        protected void RecalculateTextureRectangle()
        {
            _textureRectangle = new Rectangle(DestinationRectangle.X, DestinationRectangle.Y, DestinationRectangle.Height, DestinationRectangle.Height);
        }
    }
}
